<?php

namespace App\Services\Third;

use App\Exceptions\ExceptionHelper;
use App\Exceptions\ExceptionSms;
use App\Http\Request;

/**
 * 证件照
 * Class IdPhoto
 * @package App\Services\Third
 */
class IdPhoto
{
    private $srvUrl = 'https://idp2.market.alicloudapi.com/idphoto/make';
    private $appCode;

    public static $errorCodeMap = [
        -1      => '服务端异常',
        -10001  => '参数错误',
        -10002  => '缺少参数',
        -10007  => '服务端异常',
        -10105  => '接口权限验证失败',
        -10106  => '访问过于频繁，达到接口频率限制',
        -11004  => '照片处理失败',
        -11005  => '人脸检测失败',
        -11012  => '照片找不到',
        -11027  => '图片尺寸过大，最大边长1500',
        -211018 => '不存在人脸',

    ];

    const ID_PHONE_MAKE = '/idphoto/make';

    public function __construct($appCode)
    {
        $this->appCode = $appCode;
    }

    /**
     * 制作
     * @param $steam_path
     * @param null $width
     * @param null $height
     * @param null $size_min_kb
     * @param null $size_max_kb
     * @return mixed
     * @name:make
     * @author: lisa
     * @datetime: 2022/3/22 9:53
     */
    public function make($steam_path, $width = null, $height = null, $size_min_kb = null, $size_max_kb = null) {
        $param    = [
            "photo"     => base64_encode(file_get_contents($steam_path)),
            "dpi"       => '300',
            "spec"      => "12", # 证件照规格ID,
            'bk'        => "white", # 背景色
            'type'      => 'jpg',
            'size'      => "{$width}x{$height}", // 可选参数，证件照像素尺寸，格式:"宽x高"（中间分隔符为小写字母x），比如"480x640"。为了避免和spec内定的像素大小冲突，使用本参数的同时，需要将spec设置为"12"。
            'file_size' => "{$size_min_kb},{$size_max_kb}", // 可选参数，如果期望证件照图片的文件大小（kb）在一定的限制范围内，可以设置这个值，值的单位为kb，格式为："最小值,最大值"，比如"10,100"表示希望返回的证件照文件大小在10-100kb之间
        ];
        if (!$width && !$height) unset($param['size']);
        if (!$size_min_kb && !$size_max_kb) unset($param['file_size']);
        if (!isset($param['size']) || !isset($param['file_size'])) $param['spec'] = 1;
        return $this->idphoto_make_api($param);
    }
    /**
     * 自动裁剪
     * @param $steam_path
     * @param string $width
     * @param int $height
     * @param int $size_min_kb
     * @param int $size_max_kb
     * @return mixed
     * @name:auto_make
     * @author: lisa
     * @datetime: 2022/3/22 9:51
     */
    public function auto_make($steam_path, $width = 352, $height = 440, $size_min_kb = 25, $size_max_kb = 40)
    {
        $param    = [
            "photo"     => base64_encode(file_get_contents($steam_path)),
            "dpi"       => '300',
            "spec"      => "12", # 证件照规格ID,
            'bk'        => "white", # 背景色
            'type'      => 'jpg',
            'size'      => "{$width}x{$height}", // 可选参数，证件照像素尺寸，格式:"宽x高"（中间分隔符为小写字母x），比如"480x640"。为了避免和spec内定的像素大小冲突，使用本参数的同时，需要将spec设置为"12"。
            'file_size' => "{$size_min_kb},{$size_max_kb}", // 可选参数，如果期望证件照图片的文件大小（kb）在一定的限制范围内，可以设置这个值，值的单位为kb，格式为："最小值,最大值"，比如"10,100"表示希望返回的证件照文件大小在10-100kb之间
        ];

        return $this->idphoto_make_api($param);
    }

    function http_call($url, $body, $appcode)
    {
        $method  = "POST";
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        # 根据API的要求，定义相对应的Content-Type
        array_push($headers, "Content-Type" . ":" . "application/json; charset=UTF-8");
        # 在headers中加入Content-MD5头信息
        $content_md5 = base64_encode(md5($body, true));
        array_push($headers, "Content-MD5" . ":" . $content_md5);
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $body);

        $response    = curl_exec($curl);
        $status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $resp_body   = substr($response, $header_size);
        \Log::info("照片制作接口，响应结果：".json_encode($response, JSON_UNESCAPED_UNICODE));
        \Log::info("照片制作接口，状态码：".$status_code);
        if ($status_code != 200) {
            $resp_headers = substr($response, 0, $header_size);
            $resp_headers = explode("\r\n", $resp_headers);
            \Log::info("照片制作接口，响应头：".json_encode($resp_headers, JSON_UNESCAPED_UNICODE));
            foreach ($resp_headers as $header) {
                if (stripos($header, "X-Ca-Error-Message") === 0) {
                    ExceptionSms::returnError('请求错误');
                }
            }
            if ($resp_body) {
                $result = json_decode($resp_body, true);
                \Log::info("照片制作接口：" . json_encode($result, JSON_UNESCAPED_UNICODE));
                $status = $result['status'] ?? null;
                $msg = $result['errmsg'] ?? null;
                if (in_array($status, [-11005, -211018])) {
                    throw ExceptionHelper::getInstance(ExceptionHelper::IMAGE_INVALID);
                } else {
                    $msg = $msg ? $msg : (self::$errorCodeMap[$status] ?? "参数错误");
                    ExceptionSms::returnError($msg);
                }
            }
        }

        curl_close($curl);
        return json_decode($resp_body, true);
    }

    function idphoto_make_api($param)
    {
        $api_url = $this->srvUrl;

        $appcode = $this->appCode;

        $body  = json_encode($param);

        $result = $this->http_call($api_url, $body, $appcode);
        return $result["data"];
    }

}
